一直在不断更新对“java多线程同步的原子性”和“数据库事务的原子性”的理解。1、同步代码块的原子性在我看来,java的原子性是指为了保证共享数据多线程读写的安全性,需要保证共享数据的读-计算-写操作根据业务需求,通过一个线程。整个过程中,没有其他线程读写这个数据。Synchronized关键字不保证进入Synchronized代码块的线程不被操作系统线程调度打断,也不保证synchronized代码块执行过程中线程上下文不切换。传递了Synchronized关键字:只有获得了锁对象的monitor的线程才允许进入代码块,没有获得monitor的线程不能执行代码块,所以获得了monitor的线程会全程不读取、计算、写入共享数据。会有其他线程可以操作共享数据,实现了一个线程操作共享数据的过程中不会有其他线程参与的目的。2.数据库事务中的原子性在不断更新自己对java并发编程的理解过程中,我总是试图用数据库事务做类比。因为这个类比,我之前对数据库事务原子性的理解是:在一个事务读-计算-写同一行记录的过程中,没有其他事务也可以读-写-计算同一条记录。今天看了华为云专栏的一篇文章——事务的4个特点——让我明白了:数据库事务的原子性概念只是保证一系列操作要么全部成功,要么只要一个操作失败,会返回Rollallpreviousupdates,这个特性在mysql中是使用undolog实现的。数据库事务的隔离和隔离级别我觉得,因为数据库事务会提供多种可选的隔离级别,数据库事务比java多线程同步更复杂。多个隔离级别对数据安全的要求不同。因此,在不同的隔离级别下,事务以不同的方式控制操作。以mysql为例:如果数据库隔离级别设置为Read-Uncommited,则允许脏读(一个事务读取另一个事务未提交的数据,如果另一个事务回滚,就会发生脏读)。如果数据库隔离级别设置为Read-Commited,则允许不可重复读(在同一个事务中,前后读取同一行记录,读取的数据不一致。第二次读的时候读取了另一个事务刚刚提交的数据)如果数据库隔离表设置为Repeatable-Read,那么允许幻读(在同一个事务中,前后两次读取的记录条数不同)如果数据库隔离表设置为Serializable,则要求并发事务只能串行执行,不能并行读取。在mysql中,事务的隔离是通过mvcc+undolog来实现的。RC的隔离级别和RR的隔离级别的区别在于产生read-view的时机不一样,RC允许每读取一个snapshot就产生一个。newread-view,但是RR要求在整个事务过程中,第一次读取snapshot时会产生一个read-view,之后所有的snapshot读取都使用这个read-view,但是在事务执行update操作之后,它需要重新生成一个新的阅读视图。参考:Mysql系列(四)深入理解mysql中MVCC+行锁+表锁+间隙锁的持久化,通过redolog和两阶段提交来保证在保证数据库性能的同时,也能保证在发生意外断电时服务器在宕机等情况下数据不会丢失。原子性、隔离性、持久性,以上三个特性共同实现事务的一致性。3.Java多线程同步和数据库事务对比在写数据库事务隔离级别和数据安全要求时,我进行了分类:Read-uncommited:相当于java多线程在共享数据时并行操作,没有任何同步控制Read-commited/Repeatable-Read:相当于java多线程并行操作共享数据时使用reentrantReadWriteLockSerializable:相当于java使用Synchronized
