Transactions 同步链路

Transactions 同步链路,transactions,ejb-3.1,Transactions,Ejb 3.1,调用EJB ToToToCacheBean时发生系统异常 方法:public void…TotoCacheBean.refreshAlertCache()…: 注意:javax.ejb.EJBException:由于以下原因导致事务中止: javax.transaction.RollbackException位于 com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:334) @Singleton @P

调用EJB ToToToCacheBean时发生系统异常

方法:public void…TotoCacheBean.refreshAlertCache()…: 注意:javax.ejb.EJBException:由于以下原因导致事务中止: javax.transaction.RollbackException位于 com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:334)

@Singleton
@PersistenceContext(name=“persistence/popul”,unitName=“popul”)
@TransactionAttribute(值=TransactionAttributeType.SUPPORTS)
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@启动
公共类TotoCacheBean
{
private final ReadWriteLock=new ReentrantReadWriteLock();
@注入
私有消息道消息道;
公共枚举类型
{
全球警报
};
私有地图缓存存储;
@施工后
public void postConstruct()引发异常
{
刷新警报缓存();
刷新全局缓存();
}
@时间表(秒=“*/20”,分钟=“*”,小时=“*”,持续=假)
public void refreshAlertCache()引发异常
{
刷新缓存(类型为.ALERT);
}
@时间表(秒=“10”,分钟=“*”,小时=“*”,持续=假)
public void refreshGlobalCache()引发异常
{
刷新缓存(类型为.GLOBAL);
}       
私有void刷新缓存(类型)引发异常
{
datenow=DateTools.getDate();
LinkedHashMap messages=messageDAO.getActMessorted(现在,(type==type.ALERT));
setCache(类型,新TotoCache(消息,现在));
}
公共TotoCache getCache(类型)
{
lock.readLock().lock();
尝试
{
返回getCacheStorage().get(类型);
}
最后
{
lock.readLock().unlock();
}
}
私有void setCache(类型,TotoCache)
{
lock.writeLock().lock();
尝试
{
getCacheStorage().put(类型,缓存);
}
最后
{
lock.writeLock().unlock();
}
}
私有映射getCacheStorage()
{
if(this.cacheStorage==null)
this.cacheStorage=new HashMap();
将此文件退回存储库;
}
}`

你有解决这个问题的办法吗?LinkedHashMap没有同步,但我不想更改它,因为它将更改10个以上的类。但如果这是我做这件事的原因。
或者问题是使用ReadWriteLock?感谢您的技巧

您使用的是
并发管理类型.BEAN
&
事务属性类型。同时支持
,这两种支持相互矛盾

从文件:

仅当使用容器管理的事务划分时才能指定它

可以使用
ConcurrencyManagementType.CONTAINER
或使用
UserTransaction
界面手动管理事务

参考各种属性类型,并根据您的要求应用

LinkedHashMap未同步

默认情况下,带有
@Singleton
的bean将具有
LockType.WRITE

LockType.WRITE:用于独占访问bean实例

当客户端调用该方法时,单例会话bean将被锁定到其他客户端。因此,不需要对并发进行显式控制

@Singleton
@PersistenceContext(name = "persistence/popul", unitName = "popul")
@TransactionAttribute(value = TransactionAttributeType.SUPPORTS)
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@Startup
public class TotoCacheBean
{
    private final ReadWriteLock lock    = new ReentrantReadWriteLock();

@Inject
private MessageDAO messageDAO;

public enum Type
{
    ALERT, GLOBAL
};

private Map<Type, TotoCache>    cacheStorage;

@PostConstruct
public void postConstruct() throws DAOException
{
    refreshAlertCache();
    refreshGlobalCache();
}

@Schedule(second = "*/20", minute = "*", hour = "*", persistent = false)
public void refreshAlertCache() throws DAOException
{
    refreshCache(Type.ALERT);
}

@Schedule(second = "10", minute = "*", hour = "*", persistent = false)
public void refreshGlobalCache() throws DAOException
{
    refreshCache(Type.GLOBAL);
}       

private void refreshCache(Type type) throws DAOException
{
    Date now = DateTools.getDate();
    LinkedHashMap<String, LinkedHashMap<String, ActMessDTO>> messages = messageDAO.getActMessSorted(now, (type == Type.ALERT));
    setCache(type, new TotoCache(messages, now));
}


public TotoCache getCache(Type type)
{
    lock.readLock().lock();

    try
    {
        return getCacheStorage().get(type);
    }
    finally
    {
        lock.readLock().unlock();
    }
}

private void setCache(Type type, TotoCache cache)
{
    lock.writeLock().lock();

    try
    {
        getCacheStorage().put(type, cache);
    }
    finally
    {
        lock.writeLock().unlock();
    }
}

private Map<Type, TotoCache> getCacheStorage()
{
    if (this.cacheStorage == null)
        this.cacheStorage = new HashMap<Type, TotoCache>();

    return this.cacheStorage;
}