Java 需要使用Spring@Transactional和For Update处理并发调用
假设两个用户同时更改同一订单的订单数量,我需要处理并发问题。我想在一个名为proc\u lock的特定表中添加一个行锁,该表将包含proc\u key=order\u id。由于用户修改的是相同的订单,因此订单id对他们来说是相同的。 这个想法是第一个用户将在proc_lock表中锁定这个条目,这样当第二个用户试图锁定同一条记录时,他将无法获得锁,从而无法更新订单 我使用spring@Transactional创建事务,代码如下: BackingBean.javaJava 需要使用Spring@Transactional和For Update处理并发调用,java,jdbc,concurrency,spring-transactions,Java,Jdbc,Concurrency,Spring Transactions,假设两个用户同时更改同一订单的订单数量,我需要处理并发问题。我想在一个名为proc\u lock的特定表中添加一个行锁,该表将包含proc\u key=order\u id。由于用户修改的是相同的订单,因此订单id对他们来说是相同的。 这个想法是第一个用户将在proc_lock表中锁定这个条目,这样当第二个用户试图锁定同一条记录时,他将无法获得锁,从而无法更新订单 我使用spring@Transactional创建事务,代码如下: BackingBean.java @Transactional(
@Transactional(propagation = Propagation.REQUIRES_NEW)
public synchronized String validateItemQtyAction()
{
....
lockStatus = ((COBLIReceivingManagerService) service).processLock( procLockKey, procType);
//Check in db for row level locks. Once the call comes back here you will not find row lock.
if(lockStatus){
....
}
}
@Transactional(propagation = Propagation.REQUIRED)
public boolean processLock(String procKey, String procType)
{
boolean lockStatus = false;
try
{
lockStatus = ((COBLReceivingManagerDAO) dao).acquireLock(procKey, false);
}
catch(Exception ex)
{
WMDebugLog.DEBUG_LOG.logException(WMDebugLog.WM_COMMON_CATEGORY, ex);
return false;
}
//Check the db for row level lock. At this point the lock in db exist
return false;
}
public int acquireLock(String procKey, boolean withTimeOut)
{
JdbcTemplate jdbcTemplate = (JdbcTemplate) ILSApplicationContext.getBean("jdbcTemplate");
StringBuilder selectForUpdateSQL = new StringBuilder("SELECT 1 FROM PROC_LOCK WHERE PROC_KEY = ? FOR UPDATE ");
List<Integer> valueReturned = jdbcTemplate.query(selectForUpdateSQL.toString(), procKeyArray, intMapper);
//Check the db for row level lock. At this point the lock in db exist
if (!Misc.isNullList(valueReturned) && valueReturned.get(0) == 1)
return true;
else
return false;
}
ServiceClass.Java
@Transactional(propagation = Propagation.REQUIRES_NEW)
public synchronized String validateItemQtyAction()
{
....
lockStatus = ((COBLIReceivingManagerService) service).processLock( procLockKey, procType);
//Check in db for row level locks. Once the call comes back here you will not find row lock.
if(lockStatus){
....
}
}
@Transactional(propagation = Propagation.REQUIRED)
public boolean processLock(String procKey, String procType)
{
boolean lockStatus = false;
try
{
lockStatus = ((COBLReceivingManagerDAO) dao).acquireLock(procKey, false);
}
catch(Exception ex)
{
WMDebugLog.DEBUG_LOG.logException(WMDebugLog.WM_COMMON_CATEGORY, ex);
return false;
}
//Check the db for row level lock. At this point the lock in db exist
return false;
}
public int acquireLock(String procKey, boolean withTimeOut)
{
JdbcTemplate jdbcTemplate = (JdbcTemplate) ILSApplicationContext.getBean("jdbcTemplate");
StringBuilder selectForUpdateSQL = new StringBuilder("SELECT 1 FROM PROC_LOCK WHERE PROC_KEY = ? FOR UPDATE ");
List<Integer> valueReturned = jdbcTemplate.query(selectForUpdateSQL.toString(), procKeyArray, intMapper);
//Check the db for row level lock. At this point the lock in db exist
if (!Misc.isNullList(valueReturned) && valueReturned.get(0) == 1)
return true;
else
return false;
}
DaoImpl.java
@Transactional(propagation = Propagation.REQUIRES_NEW)
public synchronized String validateItemQtyAction()
{
....
lockStatus = ((COBLIReceivingManagerService) service).processLock( procLockKey, procType);
//Check in db for row level locks. Once the call comes back here you will not find row lock.
if(lockStatus){
....
}
}
@Transactional(propagation = Propagation.REQUIRED)
public boolean processLock(String procKey, String procType)
{
boolean lockStatus = false;
try
{
lockStatus = ((COBLReceivingManagerDAO) dao).acquireLock(procKey, false);
}
catch(Exception ex)
{
WMDebugLog.DEBUG_LOG.logException(WMDebugLog.WM_COMMON_CATEGORY, ex);
return false;
}
//Check the db for row level lock. At this point the lock in db exist
return false;
}
public int acquireLock(String procKey, boolean withTimeOut)
{
JdbcTemplate jdbcTemplate = (JdbcTemplate) ILSApplicationContext.getBean("jdbcTemplate");
StringBuilder selectForUpdateSQL = new StringBuilder("SELECT 1 FROM PROC_LOCK WHERE PROC_KEY = ? FOR UPDATE ");
List<Integer> valueReturned = jdbcTemplate.query(selectForUpdateSQL.toString(), procKeyArray, intMapper);
//Check the db for row level lock. At this point the lock in db exist
if (!Misc.isNullList(valueReturned) && valueReturned.get(0) == 1)
return true;
else
return false;
}
public int acquireLock(字符串procKey,带超时的布尔值)
{
JdbcTemplate JdbcTemplate=(JdbcTemplate)ILSApplicationContext.getBean(“JdbcTemplate”);
StringBuilder selectForUpdateSQL=new StringBuilder(“从PROC_LOCK中选择1,其中PROC_KEY=?用于更新”);
List valueReturned=jdbcTemplate.query(selectForUpdateSQL.toString(),procKeyArray,intMapper);
//检查数据库中的行级锁。此时,数据库中的锁存在
如果(!Misc.isNullList(valueReturned)&&valueReturned.get(0)==1)
返回true;
其他的
返回false;
}
该流来自BackingBeanServiceClassDaoImpl
当调用从DaoImpl返回到serviceimpl并且在serviceimpl中时,我可以在db中看到锁。但是,当调用从ServiceClass返回到BackingBean时,db中的锁将不再保留
我需要锁在DB中存在,直到我的BackingBean方法调用完成
你能告诉我这里错过了什么吗