mysql同一个事务中先插入再查询与先删除再查询结果分析

一,现象展示

1、先插入再查询

BEGIN;
INSERT INTO video (CREATE_TIME, UPDATE_TIME, VERSION, VID, VIDEO_NAME, SPEED, RATE, HORIZONTAL, VERTICAL, SIZE, LIB_ID, ALARM_THRESHOLD, ONLINE, STATUS, REMARK) 
VALUES(NOW(),NOW(),0,'vidtest','test.mp4',1,1,1,1,'1',1,0.1,20,20,'');
SELECT * FROM video WHERE VID = 'vidtest';
ROLLBACK;

结果:

在事务内部的SELECT语句可以查询到数据,但是回滚后,不能查询到数据

2、先删除再查询

BEGIN;
DELETE FROM video WHERE VID = 'vidtest';
SELECT * FROM video WHERE VID = 'vidtest';
ROLLBACK;

结果:

在事务内部的查询不能查询到数据,但是回滚后,可以查询到数据

二、原因说明:

在同一个事务中,数据需要保证一致性,也就是说,在当前的事务中,删除了就是看不到了,插入了就是多了一条数据,但这些操作都是在当前事务内部的。对于外界是隔离的。如果我们开启事务插入一条数据,还没有提交,这时新开一个事务,去查询数据,是发现不了未提交数据的。

三,基于mybatis进行测试

1、先插入再更新

//这两个操作是在同一个方法中 方法是通过Transactional注解实现事务的
@Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
//插入一条数据
int i = videoDao.insert(videoPo);
//更新一条数据
int j = videoDao.updateVid(videoPo.getId(),vid);

控制台打印的sql语句

Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5cfedd40]
JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@6624f1eb]]] will be managed by Spring
==>  Preparing: INSERT INTO video (CREATE_TIME, UPDATE_TIME, VERSION, VID, VIDEO_NAME, SPEED, RATE, HORIZONTAL, VERTICAL, SIZE, LIB_ID, ALARM_THRESHOLD, ONLINE, STATUS, REMARK) VALUES (now(), now(), 0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
==> Parameters: vid60c7d86a-111b-45ec-b25e-2100b6f9a588(String), 1.mp4(String), 1(Integer), 1(Integer), 50(Integer), 20(Integer), 30*30(String), 1(Long), 0.1000(BigDecimal), 10(Integer), 20(Integer), null
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5cfedd40]
Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5cfedd40] from current transaction
==>  Preparing: UPDATE video SET VID = ? WHERE ID = ? 
==> Parameters: vid14(String), 14(Long)
<==    Updates: 1

mybatis会将两条执行语句在同一个sqlSession中执行。

2、先删除再查询

//这两个操作是在同一个方法中 方法是通过Transactional注解实现事务的
@Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
//删除一条数据
int i = videoDao.deleteVedioByVid(vid);
//查询被删除的数据
VideoPo videoPo = videoDao.getVideoByVid(vid);

控制台打印的sql语句


Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3b1ca134]
JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@6624f1eb]]] will be managed by Spring
==>  Preparing: DELETE FROM video WHERE VID = ? 
==> Parameters: vidtest(String)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3b1ca134]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@55d43e72]
JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@1dfa23fe]]] will be managed by Spring
==>  Preparing: SELECT * FROM video WHERE VID = ? 
==> Parameters: vidtest(String)
<==    Columns: ID, CREATE_TIME, UPDATE_TIME, VERSION, VID, VIDEO_NAME, SPEED, RATE, HORIZONTAL, VERTICAL, SIZE, LIB_ID, ALARM_THRESHOLD, ONLINE, STATUS, REMARK
<==        Row: 12, 2018-10-19 15:05:15.0, 2018-10-19 15:05:15.0, 0, vidtest, test.mp4, 1, 1, 1, 1, 1, 1, 0.1000, 20, 20, 
<==      Total: 1

mybatis创建了两个sqlSession。

后来我又测试了先删除再更新的场景,发现更新失败。

结论:mybatis会再插入或删除后,进行更新操作时使用同一个sqlSession,查询时新建sqlSession。

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值