java代码 @Transactional(rollbackFor = RuntimeException.class, noRollbackFor = BizException.class)
一、事务
四个特性是什么,还是不记得的话,自己把自己拉去打靶算了 --如果只是对某些语句需要进行事务控制,则使用START TRANSACTION 语句开始一个事务比较方便,这样事务结束之后可以自动回到自动提交的方式, --如果希望所有的事务都不是自动提交的,那么通过修改AUTOCOMMIT 来控制事务比较方便,这样不用在每个事务开始的时候再执行START TRANSACTION 语句。 BEGIN; -- 开始一项新的事务(目测与START TRANSACTION是一样的) START TRANSACTION; -- 开始一项新的事务(目测与BEGIN是一样的) SET AUTOCOMMIT = 0; -- 0表示否,表示不要自动提交事务,也即是手动关闭事务 SET AUTOCOMMIT = 1; -- 1表示是,mysql默认的 ROLLBACK; -- 回滚事务 COMMIT; -- 提交事务 SHOW VARIABLES LIKE '%autocommit%' -- 查看当前是否是自动开启事务 -- 查看以及设置当前会话的隔离级别 SELECT @@session.TX_ISOLATION; SELECT @@global.TX_ISOLATION; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
二、MySQL事务隔离级别
读未提交(read-uncommitted):最低级的的错误“脏读”都扯上了(一个事务读到了另外一个还没有提交的数据),什么问题都不可以避免; 读已提交(read-committed)(Oracle默认):避免了脏读,也叫不可重复读,但还是跟可重复读(在一个事务里面,多次读到了其它事务对同一条数据的多次修改,读到的结果不一样)扯上了;
(A事务还没有提交就读到了多条其它B事务提交的数据,所以叫不可重复读) 可重复读(repeatable-read)(MySQL默认):避免了不可重复读,但是避免不了幻读(事务A统计该表总条数的时候,事务B往该表插入一条数据,事务A统计完并提交并再次统计的时候,发现多了一条数据,这就是幻读);
(A事务连续两次读取数据,中间有个B事务提交了事务,导致A事务这两次读取到的数据不一样,造成了幻读,个人理解其实该现象是正常的,毕竟是A事务是不同的两次提交了) 串行化(serializable):效率低,没有并发可言,在串行化当中,如果开启了一个事务,并没有提交,则会把这种表给锁住,另外的事务只能对该表进行读操作的,不能对该表进行写操作,所以效率就低 关于MySQL的可重复读 -- 在session1内,在同一个事务内(这个时间段内数据已经改变了),查看到的数据本来应该一样的, -- 但是如果在"读已提交"的事务隔离级别内,就会看到不同的数据(haha),造成不可重复读,因为一旦重复读,读到的数据就不一样了嘛 -- 如果在"可重复读"的隔离级别之内,就不会看到不同地方数据,也就是还是GXF -- mysql 的隔离级别是可重复读,是因为采用了MVCC的方法 BEGIN 1:00)SESSION1 SELECT t.name from USER t WHERE t.id = 1; -- GXF 2:00)SESSION1 SELECT t.name from USER t WHERE t.id = 1; -- GXF 3:00)SESSION2 BEGIN UPDATE user set t.name = 'haha' WHERE t.id = 1; END; 4:00)SESSION1 SELECT t.name from USER t WHERE t.id = 1; -- ? 5:00)SESSION1 SELECT t.name from USER t WHERE t.id = 1; -- ? COMMIT;
三、隔离级别实战
----------------------------------------------------------------------读未提交--------------------------------------------------------------------
-------------------------------------------------------读已提交,不可重复读---------------------------------------------------------
读已提交,继续:
----------------------------------------------------------可重复读-------------------------------------------------------------
幻读。。。。。
---------------------------------------------------------------串行化-----------------------------------------------------------
-----------------------------------------------------------------------------------------------------
rollback only:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();