我正在将asp.net成员资格升级到MVC4中的新简单成员提供程序。这是一个Azure / Sql Azure应用程序,可在localhost上正常运行但在部署时失败。我在事务中的代码如下:
TransactionOptions toptions = new TransactionOptions();
toptions.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
using (TransactionScope trans = new TransactionScope(TransactionScopeOption.Required, toptions))
{
try
{
... do a bunch of database stuff in a single dbContext ...
var roleprov = (SimpleRoleProvider)Roles.Provider;
string[] roles = roleprov.GetRolesForUser(Username);
// above line fails with The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024)
}
}
我正在使用this technique来填充Roles类。堆栈跟踪似乎表明它确实试图触发子事务来完成该调用。 simplemembership表位于不同的db中。如何在单独事务的上下文中从角色提供程序检索角色信息?
答案 0 :(得分:0)
问题是GetRolesForUser
导致新连接打开到第二个数据库,而这又反过来发现它位于TransactionScope
。反过来,这(MSDN - System.Transactions Integration with SQL Server)然后升级到DTC。你可以尝试一些选择:
在交易开始前获取角色
您可以在<{1}}之外检索<{1}} 。你是否有理由将它们纳入范围?鉴于你说:
如何从单独事务上下文中的角色提供程序中检索角色信息
听起来你可以在string[] roles
之前获得角色信息并且没有任何问题。
关闭简单会员连接字符串上的交易
您可以通过在连接字符串中添加“enlist = false”(请参阅SqlConnection.ConnectionString
)来告知连接字符串不参与事务,因此如果您从不需要事务处理,这可能是一个选项。您用于简单会员的数据库。
尝试在交易前打开简单会员连接
对于才关闭它。 Scratch,在每次调用TransactionScope
,它创建了它的数据库对象,然后在第一次使用它时打开它。但是,直到...... TransactionScope
时打开连接,这样你就不走运了。我以为你可以在打开SimpleRoleProvider
之前拨打GetRolesForUser
一次,然后再使用已经打开的连接在范围内打电话 - 你不能。
使用GetRolesForUser
免责声明:我不能保证这会有效,因为我无法使用您的设置进行测试。
您可以通过首先在事务范围外打开非事务连接字符串来阻止使用两个连接字符串进行提升,然后不应提升事务。如果在同一事务范围内导致与TransactionScope
然后IObjectContextAdapter
相同的连接(否则会导致升级),也可以使用此方法。
您可以尝试使用您的上下文,并查看是否停止了GetRolesForUser促销事务,但我怀疑这是否有效,因为Close
导致连接打开(如果尚未打开)。由于我无法在您的场景中进行测试,因此我会将其包含在内以防万一。
Open