之前一直有一个误区,以为事务内的查询也是携带行级锁的,这个是有问题的今天试了一下; 先看一下我的name表;
这里的age是主键! 其他值不用过多关注
// 这通过查询加了一个显示锁也就是悲观锁没有commit;
begin;select * from name where age = 18 for update;
// 普通查询 可以查询出来,不经过锁
select * from name where age = 18;
// 这通过查询加了一个显示锁也就是悲观锁没有commit;
begin;select * from name where age = 18 for update;
// 显示加锁查询 等待锁释放
begin;select * from name where age = 18 for update;
// 这通过查询加了一个显示锁也就是悲观锁没有commit;
begin;select * from name where age = 18 for update;
// 无论是否有事务的更新删除等操作都需要等到锁释放
.................
注意:for update必须要在事务包裹的前提下才有效,其次for update只对查询有效,且如果是有关联表的sql后面加了for update那么所有关联到的数据都会被锁住,直到行级锁所在事务被commit;
是否有相关如果不使用事务那么sql不commit可以更新吗?
我们开两个窗口目前表里面有两条数据,且关闭自动提交
窗口2已经insert了一条数据但是窗口一还是没查到,直到commit之后才查询到,我们平时使用的事务,就是已经在最后写好了commit所以才感知不到commit的存在,不过如果我们关闭了自动提交那么在drop或者create之类的操作的时候也会commit
没有事务 关闭自动提交,会出现死锁吗?
我们左边更新id为123的数据不commit 右边也修改id为123的数据这时候就出现了等待的情况也就是死锁
这种情况会出现在我们如果使用了线程池去操作表,并且数据库关闭了自动提交 如果出现了要修改相同索引
的数据那么就会出现死锁 !
mysql会话事务和@Transactional(rollbackFor = Exception.class)
要知道@Transactional在切面里面是关闭了autocommit的也就是说被注释的方法等于全部都在一个事务里面了
表里一开始有一条数据,之后我们关闭自动提交进行插入和修改操作 注意,是没有开启事务的,
之后通过rollback操作 最后发现表里的数据没变化 如果开启了自动提交那就不一样了,用户
每次操作都会直接入库,不在收最后的rollback或者commit限制,但是@Transactional就自动
关闭了autocommit所以实现了全部提交和回滚;
这时候会有同学要问:如果我关闭了数据库的自动提交,在接口上面不加事务是不是数据永远进不了数据库呢?
这个问题其实也困扰了我很久我做了测试,关闭了数据库的自动提交 接口不加事务但是数据还是可以进入到数据库 百度了一下发现原来是因为我们使用了MySQL的JDBC驱动包 mysql-connector-java 会给会话的connection默认开启自动提交包括我们平时使用的连接池druid也一样是可以自动提交的