【发布时间】:2019-03-26 04:39:26
【问题描述】:
我需要使用 Spring 和 MariaDB 解决资源预留模式。 问题很简单,我有一张来宾表,用于存储活动的客人姓名,我必须确保活动的客人人数必须小于或等于最大容量。
这是桌子:
create table guest(
event int,
name varchar(50)
)
create index event on guest (event);
什么是正确的数据库锁定程序和隔离级别? 请考虑此代码将在多线程容器中运行。 我选择使用“SELECT...FOR UPDATE”锁定表,以将锁定限制在一个事件行中。
// START TRANSACTION
@Transactional
public void reserve(int event, String name){
getJdbc().query("SELECT * FROM guest WHERE id=? FOR UPDATE",event);
Integer count=getJdbc().queryForObject("SELECT COUNT(*) FROM guest WHERE id=?",Integer.class,event);
if(count>=MAX_CAPACITY)
throw new ApplicationException("No room left");
getJdbc().query("INSERT INTO guest VALUES (?,?)",event,name);
}
// COMMIT
我做了一些测试,似乎我需要 READ_COMMITTED 隔离级别,对吗? 这是我发现的:
这是我第一次必须更改隔离级别,对此我感到有些惊讶,您能否确认标准 MariaDB 隔离级别 REPETABLE_READ 因这种模式而失败?
【问题讨论】:
-
Spring 是否添加了
START和COMMIT?当它throws时它会做ROLLBACK吗? -
漂亮的图形和问题的解释。
-
@RickJames,是的,如果事务管理器启用了事务注释(在这里您还可以指定隔离级别和异常的回滚策略)
-
什么是“事务管理器”的一部分?
-
它是一个Spring组件,它使用cglib(或其他替代品)来拦截事务方法入口和出口管理db事务docs.spring.io/spring/docs/4.2.x/spring-framework-reference/…
标签: locking mariadb spring-jdbc isolation-level