同步链接

时间:2013-03-27 11:10:02

标签: transactions ejb-3.1

在EJB TotoCacheBean上调用期间发生系统异常,

  

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

@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;
}

}`

您有什么想法来解决这个问题吗? LinkedHashMap没有同步,但我不想改变它,因为它将改变10个以上的类。但如果这是我会这样做的原因。 或问题是使用ReadWriteLock?谢谢你的伎俩

1 个答案:

答案 0 :(得分:0)

您正在使用ConcurrencyManagementType.BEAN&amp; TransactionAttributeType.SUPPORTS在一起是矛盾的。

来自文档:

  

只能在使用容器管理的事务划分时指定它。

要么ConcurrencyManagementType.CONTAINER要么使用UserTransaction界面手动管理交易。

请参阅here了解各种属性类型&amp;根据您的要求申请。

  

LinkedHashMap未同步......

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

  

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

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