事物
事物遵循ACID原则
原子性(atomicity): 事物要么成功提交, 要么全部不提交,是一个整体。
一致性(consistency): 事物的执行从一种正确的状态转换为另一种状态
隔离性(isolation): 在事物正确提交之前, 不允许将该事物对数据的改变提供给其他的事物;
持久性(durability): 事物正确提交后 , 数据将被持久化到数据库
数据库的事物
read uncommited: 读未提交, 那么可能产生脏读, 读到其他事物没有提交的数据
read commited: 度已提交, 只有一个事物提交完成后, 才可去读, 那么可能出现不可重复的
repeatable read : 重复的,读完后加锁, 但是如果有insert 事物的提交会有幻读
serializable: 串行化的执行事物;
2019-7-30 18:40:44更新参考了https://www.cnblogs.com/yubaolee/p/10398633.html
第一类丢失: 有2个事物开始更新同一个记录, 有个事物更新成功了, 另外一个事物失败导致了回滚,导致成功的事物的数据也丢失了
50---> A -- 开始更新数据为100 数据库显示更新成功为100
50---> B -- 开始更新数据为100 失败 回滚 数据库还是50
导致A事物更新成功的数据100丢失了;
第二类丢失: 有2个事物对同一个记录进行了更新,后更新执行成功的事物导致先完成更新事物的数据丢失
50 -- > A -- >更新为100
50 -- > B -- >更新为200
最终的结果为200, 导致A更新的那个值丢失了 (有点像cas ABA 问题)
脏读: 事物读到了另外一个事物没有提交的数据
不可重复读: 1个数据读数据库2次, 但是在中途有个数据对该记录进行了更新,导致2次读取的结果不一致
幻读: 1个数据读数据库2次, 但是中途有个数据插入了一条记录,导致2次读取的结果集不一致
隔离界别 | 脏读 | 不可重复读 | 幻读 | 丢失更新1 | 丢失更新2 |
---|---|---|---|---|---|
read uncommited | 会 | 会 | 会 | 不会 | 会 |
read commited | 不会 | 会 | 会 | 不会 | 会 |
repeatable read | 不会 | 不会 | 不会 | 不会 | 不会 |
serializable | 不会 | 不会 | 不会 | 不会 | 不会 |
spring 事物的传播和隔离级别
来自java类 :org.springframework.transaction.TransactionDefinition
PROPAGATION_REQUIRED:Support a current transaction; create a new one if none exists.
如果没有事物创建一个新的事物, 如果有事物,使用事物执行;
PROPAGATION_SUPPORTS:Support a current transaction; execute non-transactionally if none exists
如果有事物,以事物的方式执行, 如果没有事物 以非事物的方式执行;
PROPAGATION_MANDATORY: Support a current transaction; throw an exception if no current transaction
如果有实物,以事物的方式执行,如果没有事物抛异常
PROPAGATION_REQUIRES_NEW:Create a new transaction, suspending the current transaction if one exists.
创建一个新的事物, 如果当前存在事物,将当前的事物暂停
PROPAGATION_NOT_SUPPORTED:Do not support a current transaction; rather always execute non-transactionally.
以非事物的方式执行, 如果当前存在事物,那么暂停事物
PROPAGATION_NEVER:Do not support a current transaction; throw an exception if a current transaction
以非实物的方式执行, 如果当前有实物那么抛异常
PROPAGATION_NESTED: Execute within a nested transaction if a current transaction exists,
behave like {@link #PROPAGATION_REQUIRED} otherwise
如果当前存在事物,那么以嵌套事物的方式执行, 如果当前没有事物, 那么按照required 的方式执行;
ISOLATION_DEFAULT:Use the default isolation level of the underlying datastore
使用当前数据库的默认的事物隔离级别
事物传播行为介绍:
@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没有声明事务,那就不用事务.
事物超时设置:
@Transactional(timeout=30) //默认是30秒
事务隔离级别:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
读取未提交数据(会出现脏读, 不可重复读) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED)
读取已提交数据(会出现不可重复读和幻读)
@Transactional(isolation = Isolation.REPEATABLE_READ)
可重复读(会出现幻读)
@Transactional(isolation = Isolation.SERIALIZABLE)
串行化
不可重复读重点在于update和delete,而幻读的重点在于insert
参考了:https://www.cnblogs.com/jimmy-muyuan/p/5722708.html