事务
原子性(Atomicity)
原子性:记录之前的版本,允许回滚
一致性(Consistency)
一致性:事务开始和结束之间的中间状态不会被其他事务看到
持久性(Durability)
一个事务一旦提交,他对数据库的修改应该永久保存在数据库中
隔离性(Isolation)
问题:如果两个并发事务(A事务和B事务)修改数据库表同一行数据,那会出现什么情况。
可能最后结果是以A事务覆盖B事务结果,或者反过来。
这时候数据库需要有个机制进行控制,避免这种情况出现,那就是隔离级别,数据库提供了多种隔离级别。
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这不变成T1,T2串行了嘛。
我认为这个只是局部的串行,也就是只有在相互影响的事务之间,因为设置隔离级别后,会对影响的行或者表进行加锁,不会对整个数据库的表或者行加锁。所以不会影响其它事务的并行执行。
事务隔离级别
前面说的事务的四大特性,都只是理论上的。实际上的控制是由事务隔离级别来做的。
事务的隔离级别需要解决的问题:
-
脏读
某个事务读取到了另一个事务未提交的数据。
但是要区分一种情况,
当前事务提交的数据自己会读到,这不算脏读 -
不可重复读
事务在执行过程中,前后两次读取到的数据不一致。这中间肯定发生了其它事务提交或者修改了数据,按理说这也没错,毕竟其它事务修改了数据并提交了,你读到也是正常的。但是从程序控制来说,两次读到不同数据,会对程序逻辑产生无可估计的影响以及错误。
描述:事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,但此时事务T1还没执行完,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。 -
虚读,幻读
事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
隔离级别
【1】mysql事务隔离级别
https://www.cnblogs.com/dooor/p/5303904.html
【2】java事务及隔离级别http://blog.csdn.net/wang379275614/article/details/24818397
- Serializable (串行化):可避免脏读、不可重复读、幻读的发生
- Repeatable read (可重复读):可避免脏读、不可重复读的发生
- Read committed (读已提交):可避免脏读的发生
- Read uncommitted (读未提交):最低级别,任何情况都无法保证
隔离级别的设置
隔离级别设置是会话级别的,数据库会有个默认或者全局的会话级别设置。
-- MYSQL
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL
[
READ UNCOMMITTED
|READ COMMITTED
|REPEATABLE READ
|SERIALIZABLE
]
事务隔离级别与数据库锁的关系
事务隔离级别是通过加锁的机制实现的。
隔离级别的基础是锁和版本号。
java多数据源
JTA
XA连接不支持JDBC的自动提交特性, 也就是说应用程序不必在XA连接上调用java.sql.Connection.commit()或java.sql.Connection.rollback()。相反,应用程序应该使用UserTransaction.begin()、UserTransaction.commit()和UserTransaction.rollback()
两阶段提交
资料
【1】java和mysql事务
https://www.cnblogs.com/fjdingsd/p/5273008.html
网友评论