使用下面的代码连接数据库
private static Connection connection() {
try {
Class.forName(com.microsoft.sqlserver.jdbc.SQLServerDriver.class.getName());
Connection out= DriverManager.getConnection("jdbc:sqlserver://172.23.47.6:1433","sa","Test2020.");
out.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
return out;
}catch (Exception e){
throw new RuntimeException(e);
}
}
令人诧异的是,在TRANSACTION_READ_UNCOMMITTED的情况下表现和mysql的表现一致,但是对其其他三个隔离级别都是表现如下
update transaction_table set curr_value=1 where id=valueA
这个表现算是标准的TRANSACTION_SERIALIZABLE了吧。
如果对代码进行调整,让read先执行,则打印结果如下
valueA | 0
valueB | 0
valueC | 0
update transaction_table set curr_value=1 where id=valueA
总的感觉是MsSql把事务分为互斥(而不是MVCC)和非互斥。一旦有写入,则加锁,然后就不能读了。并且这个加锁是针对整个表而言的。例如将printDB改为如下所示
private static void printDB(Connection connection) throws SQLException {
PreparedStatement select = connection.prepareStatement("select * from transaction_table where id='valueB'");
ResultSet resultSet = select.executeQuery();
while (resultSet.next()) {
System.out.println("\t" + resultSet.getString(1) + " | " + resultSet.getInt(2));
}
}
此时仍然不能避免printDB阻塞