上下文:使用的框架是Spring,所有查询都使用JdbcTemplate运行。Mysql Server版本是5.6.19。和table
是InnoDB table
,默认设置为,并且设置了auto commit
隔离级别可重复读取。
问题:Insert
在事务内部发生的事情和select
读取相同插入数据的事务看不到该数据。在select
运行后,在insert
之后的insert
交易都有commited
。
我已经启用bin日志以及mysql中的常规日志。以下相关日志
二进制日志:
SET TIMESTAMP=1438265764/*!*/;
BEGIN
/*!*/;
# at 249935389
#150730 14:16:04 server id 1 end_log_pos 249935606 CRC32 0xa6aca292 Query thread_id=40 exec_time=0 error_code=0
SET TIMESTAMP=1438265764/*!*/;
insert into user_geo_loc_latest(user_id, lat, lng) values(x,y,z) on duplicate key update lat=y, lng=z
/*!*/;
# at 249935606
#150730 14:16:06 server id 1 end_log_pos 249936255 CRC32 0x2a52c734 Query thread_id=40 exec_time=0 error_code=0
SET TIMESTAMP=1438265766/*!*/;
INSERT INTO table(txnid) VALUES ('885851438265675046')
/*!*/;
# at 249936255
#150730 14:16:06 server id 1 end_log_pos 249936514 CRC32 0x6cd85eb5 Query thread_id=40 exec_time=0 error_code=0
SET TIMESTAMP=1438265766/*!*/;
INSERT INTO table2(x) VALUES (y)
/*!*/;
# at 249936514
#150730 14:16:06 server id 1 end_log_pos 249936545 CRC32 0xceb9ec56 Xid = 9406873
COMMIT/*!*/;
查询日志
150730 14:16:04 40 Query ...
....
40 Query select count(*) from table where txnid = '885851438265675046'
40 Query select @@session.tx_read_only
40 Query INSERT INTO table(txnid) VALUES ('885851438265675046')
40 Query select @@session.tx_read_only
40 Query INSERT INTO table2(x) values(y)
40 Query commit
....
150730 14:16:07 36 Query select pp.*, b.create_date from table pp left join bill b on pp.bill_id = b.bill_id where pp.txnid = '885851438265675046'
奇怪的是,First insert
(249935389)根本不应该成为交易的一部分。这是一个单独的API调用,完全不相关。可能是弹簧将其与事务混合在一起,还是我在读取错误的日志?AFAIK,因为它在同一线程上,这意味着插入在事务中。
接下来的两个inserts
是事务的一部分,看起来像提交了。(249936514)。现在,选择查询(一般日志中的最后一个查询)在提交后运行,并且看不到数据。它返回0行。考虑到数据是committed
怎么发生的?还是commit
不在线程40上?由于它没有线程ID。
总而言之,我有两个问题。
是否
BEGIN
在二进制日志之中之前INSERT INTO user_geo_loc
(这是不交易的一部分),这与春季/ JDBC或MySQL错误简单地做到这一点,因为它知道这个交易已经承诺(如交易被写入时,他们已经以BINLOG成功),因此永远不会回滚。给定提交发生在select之前(commit在14:16:06且select在14:16:07),那么select如何不返回事务插入的行呢?
这非常令人困惑。任何帮助,将不胜感激
注意:bin和查询日志中的查询均已编辑,以删除敏感信息。但是查询的本质保持不变
编辑:更新了常规日志和查询日志,并附有详细示例。
BEGIN
或START TRANSACTION
。您是在使用autocommit=0
吗?(我更喜欢begin ... commit;它使交易的范围变得清楚。)