Skip to main content

后端transaction

后端 Transaction

@Transaction系列API

  • @Transaction(propagation = Propagation.REQUIRED):如果有事务就加入事务,没有的话就加入事务
  • @Transaction(propagation = Propagation.NOT_SUPPORT):容器不为这个方法开启事务
  • @Transaction(propagation = Propagation.REQUIRED_NEW):不管是否存在事务,都创建一个新的事物,原来的挂起,新的执行完毕之后,继续执行老的事务
  • @Transaction(propagation = Propagation.MANDATORY):必须在一个已有的事务里面执行,否则抛出异常
  • @Transaction(propagation = Propagation.NEVER):必须在一个没有的事务里面执行,否则抛出异常
  • @Transaction(propagation = Propagation.SUPPORT):如果其他的bean调用这个方法,在其他的bean里面声明了事务就使用事务,如果其他的bean里面没有声明事务,那就不用事务
  • @Transaction(isolation = Isolation.READ_UNCOMMITTED):读取未提交的数据(会出现脏读,不可重复读的)基本不使用
  • @Transaction(isolation = Isolation.READ_COMMITTED):读取已经提交的数据(会出现不可重复读还有幻读)SQLSERVER默认。因为读取已提交的数据,未提交的数据不能读,所以避免了脏读的问题。
  • @Transaction(isolation = Isolation.REPEATABLE_READ):可重复性读(会出现幻读)MYSQL默认。因为读走的数据加了锁,这样别的数据就不能改,避免了不可重复性读的问题。但是还是会出现幻读,因为可能会有别的事务添加几行新数据,这就导致可能两次相同的读取在后一次读取的时候发现多出来几行
  • @Transaction(isolation = Isolation.SERILIZABLE):串行化执行,最严格的级别。把整个表格锁死,幻读也可以避免了!

读锁, 写锁, 独占写锁

乐观离线锁: 认为冲突概率不高, 一般的实现是版本号 ... WHERE version = this_session.version

悲观离线锁: 认为冲突概率高, 强制事务先锁

单机的悲观锁可以是lock, synchronized之类, 进程共享的悲观锁必须要有一个进程共享的“lockable token”, 例如数据库锁

  • 粗粒锁Coarse-Grained Lock :把根数据相关的,比如外键关联的所有的数据全部锁死。实现原理;两组数据通过引用共享同一个版本号码,通过引用的方法,两个数据引用的是同一个版本号码。