本文共 3723 字,大约阅读时间需要 12 分钟。
事务的概念:数据库事务是访问并可能更新数据库中各种数据项的一个程序执行单元。
事务的组成:一个数据库事务通常包含对数据库进行读或写的一个操作序列。
一个典型的数据库事务:
BEGIN TRANSACTION//事务开始SQL1SQL2COMMIT/ROLLBACK//事务提交或回滚
事务使系统能够更方便的进行故障恢复以及并发控制,从而保证数据库状态的一致性。
总结:
事务并发操作同一批数据的时候所导致的问题可以通过设置隔离级别来解决。
隔离级别从小到大安全性越来越高,但是效率越来越低
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | √ | √ | √ |
读提交 | × | √ | √ |
可重复读 | × | × | √ |
可串行化 | × | × | × |
在使用,可重复读时,MySQL等成熟的数据库已经通过锁机制在默认隔离级别的时候,就避免了幻读的出现。
如果多个线程操作,基于同一个查询结构对表中的记录进行修改,那么后修改的记录将会覆盖前面修改的记录,前面的修改就丢失掉了,这就是丢失更新。分为两类:回滚丢失和覆盖丢失。
解决办法
悲观锁机制:假定这样的问题是高概率的,最好一开始就锁住,免得更新老是出错。
select*from account lock in share mode;
当A事务把某一个数据用共享锁锁住之后,B事务就只能对该数据进行查看,不能进行任何修改操作。select*from account for update;
当A事务把某一个数据用排他锁锁住之后,B事务不能对该数据进行任何操作。乐观锁机制:假定这样的问题是小概率的,最后一步做更新的时候再锁住,免得锁住时间太长影响其他人做有关操作。
在用户并发数比较少且冲突比较严重的应用系统中选择悲观锁-排他锁方法,其他情况首先考虑乐观锁版本列更新的方法
数据库命令:
select version()
;select @@session.tx_isolation
;set @@session.tx_isolation=级别参数
;READ-UNCOMMITTED,READ-COMMITTED,REPEATABLE-READ,SERIALIZABLE
;start transaction
;commit/rollback
参数 | 功能 |
---|---|
readOnly | 该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transaction(readOnly=true) |
rollbackFor | 该属性用于设置需要进行回滚的异常数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transaction(rollbackFor=RuntimeException.class) ,指定多个异常类:@Transaction({rollbackFor=RuntimeException.class,Exception.class}) 。默认异常指的是运行时异常或者error错误 |
rollbackForClassName | 该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称:@Transaction(rollbackForClassName="RuntimeException") ,指定多个异常类名称:@Transaction(rollbackForClassName="RuntimeException","Exception") |
noRollbackFor | 该属性用于设置不需要进行回滚的异常数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transaction(noRollbackFor=RuntimeException.class) ,指定多个异常类:@Transaction({noRollbackFor=RuntimeException.class,Exception.class}) 。 |
noRollbackForClassName | 该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transaction(noRollbackForClassName="RuntimeException") ,指定多个异常类名称:@Transaction(noRrollbackForClassName="RuntimeException","Exception") |
propagation | 该属性用于设置事务的传播行为。例如:@Transaction(propagation=Propagation.NOT_SUPPORTED) |
timeout | 该属性用于设置事务的超时秒数,默认值为**-1**表示永不超时 |
isolation | 该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置。@Transactional(isolation=Isolation.READ_UNCOMMITTED) |
Transactional(propagation=Propagation.REQUIRED)
:如果有事务,那么加入事务,没有的话新建一个(默认情况下)Transactional(propagation=Propagation.NOT_SUPPORTED)
:容器不为这个方法开启事务;Transactional(propagation=Propagation.REQUIRES_NEW)
:不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务;Transactional(propagation=Propagation.MANDATORY)
:必须在一个已有的事务中执行,否则抛出异常;Transactional(propagation=Propagation.NEVER)
:必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)Transactional(propagation=Propagation.SUPPORTS)
:如果其他bean调用这个方法,在其他bean中声明事务,那就用事务。如果其他bean没有声明事务,那就不用事务。转载地址:http://nmugn.baihongyu.com/