在MySQL数据库中存在一张settings表:
sname | svalue |
---|---|
no | 0 |
no2 | 0 |
同时存在以下两个函数:
CREATE FUNCTION `fn_inc_no`() RETURNS int(11)
BEGIN
DECLARE val INT DEFAULT 0;
UPDATE settings
SET svalue = svalue + 1
WHERE sname = 'no';
SELECT svalue INTO val FROM settings WHERE sname = 'no';
RETURN val;
END
和
CREATE FUNCTION `fn_inc_no2`() RETURNS int(11)
BEGIN
DECLARE val INT DEFAULT 0;
UPDATE settings
SET svalue = svalue + 1
WHERE sname = 'no2';
SELECT svalue INTO val FROM settings WHERE sname = 'no2';
RETURN val;
END
如果此时在Java程序中运行如下代码:
Statement query = conn.createStatement();
ResultSet rs = query.executeQuery("SELECT fn_inc_no() AS no, fn_inc_no2() AS no2");
在多个线程(测试时使用了10个线程)中多次(测试时重复执行10000次)执行以上代码,最后得到的 no 和 no2 总是相等的。这是否说明了这条SELECT语句当中的fn_inc_no和fn_inc_no2总是在同一个事务中执行的,是否说明此条SELECT语句在MySQL中本身是一个原子操作?
不同的函数操作的两个不同行,说明不了任何问题。
前条语句更新,后条语句查询,肯定返回的是更新后的结果。
也不用多个线程循环,你让两个函数操作同一行记录, 第一赋值为3,第二个不赋值,直接查询,看看能不能查询出3即可。
不同的函数调用是在不同的事务中。
本来就是2行,你分别更新,分别查询相同的次数, 结果集肯定一样啊?凭啥不一样。
在mysql数据库中创建了settings和settings两张表:
settings:
sname | svalue |
---|---|
no | 0 |
settings2:
sname | svalue |
---|---|
no | 0 |
同时有两个函数分别对这两张表进行修改:
DELIMITER $$
CREATE FUNCTION `fn_inc_no`() RETURNS int
DETERMINISTIC
BEGIN
DECLARE val INT(11) DEFAULT 0;
UPDATE settings
SET svalue = svalue + 1
WHERE sname = 'no';
SELECT svalue INTO val
FROM settings
WHERE sname='no';
RETURN val;
END$$
DELIMITER ;
DELIMITER $$
CREATE FUNCTION `fn_inc_no2`() RETURNS int
DETERMINISTIC
BEGIN
DECLARE val INT(11) DEFAULT 0;
UPDATE settings2
SET svalue = svalue + 1
WHERE sname = 'no';
SELECT svalue INTO val
FROM settings2
WHERE sname='no';
RETURN val;
END$$
DELIMITER ;
执行以下语句:
SELECT fn_inc_no() AS no1, fn_inc_no2() AS no2;
然后执行
-- 需要开启binlog
-- <binlog>替换为binlog文件名,<pos>替换为binlog文件中的起始位置
SHOW BINLOG EVENTS IN '<binlog>' FROM <pos>
可以发现fn_inc_no和fn_inc_no2是在相同的事务中执行的:
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
| ----------------- | --------- | -------------------- | --------- | ----------- | ----------------------------------------------------------------- |
| mysql-bin.000055 | 916835895 | Anonymous_Gtid | 133026001 | 916835974 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000055 | 916835974 | Query | 133026001 | 916836058 | BEGIN |
| mysql-bin.000055 | 916836058 | Table_map | 133026001 | 916836119 | table_id: 3885 (test.settings) |
| mysql-bin.000055 | 916836119 | Table_map | 133026001 | 916836181 | table_id: 3887 (test.settings2) |
| mysql-bin.000055 | 916836181 | Update_rows | 133026001 | 916836231 | table_id: 3885 |
| mysql-bin.000055 | 916836231 | Update_rows | 133026001 | 916836279 | table_id: 3887 flags: STMT_END_F |
| mysql-bin.000055 | 916836279 | Xid | 133026001 | 916836310 | COMMIT /* xid=92321411 */ |