事务的特性
事务的特性没什么可说的。老生常谈的问题了。
原子性:就是说数据库的一次操作是一个集合,要不全部执行成功,要不全部执行失败。这个操作是逻辑上是最小单位的操作。
比如在一个事物里你查询,然后插入,然后在更新等,无论你 多数据库操作了多少回。这都算作一个操作。
一致性:同一时刻查到的类型数据应该是一致的。不可能事务A查到一条数据,事务B就查到两条数据。数据库系统是不允许出现的 。
隔离性:事务与事务中间的操作是独立的,互补影响。
持久性:事务一旦提交,就会保存在数据库里。只要不去修改,它就永远是那样的一个状态。
事务中出现的问题
脏读:一个事务在读取的时候,读取了另一个事务尚未提交的数据。
不可重复读:事务A里有两次查询数据存在。但是在两次查询中,有事务B对数据进行了操作。导致事务A两次查询的数据不一致。这就是不可重复读问题。不可重复读主要是对于更新的操作来说的。
幻读:可重复读类似,只不过该主要针对于范围读。怎么说呢。比如事务在一次查询中两次查询ID大于10的数据。但是两次查询过程中,有一个事务存入了ID为11或者删除了ID为12的数据。那么对于事务A来说就造成了两次查询的不一致。
4个隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read-uncommitted) | 是 | 是 | 是 |
不可重复读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
上面说的问题是针对于普遍数据库的隔离级别而言的。对于mysql的inndb的可重复读是不存在幻读问题呢。
inndb的可重复读对于普通的查询来说,是基于快照读的方式实现的。在事务开启后,会生成当前数据版本的一个快照。以便于在本次事务内查到的数据都是一样的。也就是说查到的数据是历史版本数据。
乐观锁:主张数据库中间的并发竞争资源的概率是比较小的,所以等到更新的时刻才进行加锁处理,一般不是并发很高的数据库都是这样做的。一般处理有在数据库的字段加上版本号字段。每次更新数据库时,都会根据版本号来进行更新,并且更新成功会把版本号加1。 实例如下 查询出商品信息后,生成订单,然后在更新商品信息。
1.查询出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根据商品信息生成订单
3.修改商品status为2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};
悲观锁:主张一碰到数据就加锁,认为数据的竟态很常见。
间隙锁:比如要查询ID为小于10大于5的数据,那么数据库会把ID在5和10中间的数据全部加锁。即使数据库并不存在ID为6,7,8的数据,这样做有什么好处呢?比如事务A查询ID小于10大于5的记录。那么其他事务就不可以在事务A查询过程中插入ID小于10大于5的记录。这样可以防止幻读。
行锁:针对于表锁来说,Inndb里有行锁。但是,但是,但是:Inndb的行锁是对索引加锁来实现的。换句话说如果你没有使用索引的话,那么你就是表锁。
表锁:很简单,就是对整张表来加锁。比如:delete from tablea
页锁:说实话,没听说过。
X锁:排他锁,在数据发生,更新,插入,删除时出现。查询使用 for update关键字也会加上X锁。
S锁:在数据查询特定查询时出现,对于加上 share in mode 加上共享锁。
事务回滚,自增长ID会增长
在进行数据存入的过程时,会发生事务回滚,但是对于自增长的id列并不会回滚。这是因为mysql的id自增长是依据内存来实现的,而事务是根据日志记录来实现的。而且依据自增长ID的实现,是不可能参与到事务的。因为在批量插入的过程中。总不能等你前一条提交了。后一条才能进行吧。这样数据库就死了。
测试
这个没什么好说的,依据官方和各位大神的文章,进行测试。可以根据mysql 的session会话来测试,也可以自己写代码进行测试。无论哪种测试,总会发生不可预料的问题。
如果你能够看到文末的话,那么分享下所看到的一些资料:
http://hedengcheng.com/?p=771
https://blog.csdn.net/tangkund3218/article/details/47904021
https://blog.csdn.net/lishenglong666/article/details/53913126
https://blog.csdn.net/fly2nn/article/details/70239809
https://blog.csdn.net/silyvin/article/details/77482920