我们正在考虑在Java EE中开发关键任务应用程序,并且让我印象深刻的一件事是平台中缺少会话隔离.让我解释一下这个场景.
我们有一个原生的Windows应用程序(一个完整的ERP解决方案),每月从稀疏的贡献者那里获得大约2k LoC和50个bug修复.它还支持脚本,因此客户可以添加自己的逻辑,我们不知道这样的逻辑是做什么的.每个服务器节点都有一个代理和一个进程池,而不是使用线程池.代理接收客户端请求,将其排队直到池化实例空闲,向该实例发送请求,向客户端传递响应,并将实例释放回进程池.
这种体系结构非常强大,因为有这么多稀疏贡献和自定义脚本,所以部署版本有一些严重的错误,例如无限循环,长时间等待的悲观锁定,内存损坏或内存泄漏,这种情况并不少见.我们实现了内存限制,请求超时和简单的监视器.只要某个进程无法正确及时地回答,代理就会杀死它,因此看门狗会检测并启动另一个实例.如果进程在开始响应请求之前崩溃,则代理会将相同的请求发送到另一个池化实例,并且用户不知道服务器端的任何故障(管理日志除外).这很好,因为有些实例在处理请求时会被伪代码慢慢删除.因为大多数会话数据都保存在客户端或(在极少数情况下)共享存储中,所以它似乎完美无缺.
现在考虑转向Java EE,我在规范或流行的应用程序服务器上找不到类似的东西,比如Glassfish和JBoss.是的,我知道大多数集群实现都使用会话复制进行透明故障转移,但是我们有一些小公司在一个简单的双节点集群上使用我们的系统(我们也有冒险者在单节点服务器上使用该系统) .使用线程池,我理解一个错误的线程可以使整个节点关闭,因为服务器无法检测并安全地杀死它.将整个节点关闭比杀死单个进程要糟糕得多 - 我们有部署,其中每个节点有大约100个池化流程实例.
我知道IBM和SAP已经意识到了这个问题
, 分别.但基于最近的JSR,论坛和开源工具,社区上没有太多活动.
现在问题来了!
如果你有类似的场景并使用Java EE,你是如何解决的?
您是否了解即将推出的开源产品或Java EE规范中可以解决此问题的更改?
.NET有同样的问题吗?你能解释或引用参考文献吗?
您是否了解一些可以解决此问题的现代开放平台,并且值得完成ERP业务逻辑的任务?
拜托,我不得不告诉你不要做更多的测试或任何类型的QA投资,因为我们不能强迫我们的客户在他们自己的脚本上做这个.我们还有一些案例,其中紧急错误修复必须绕过QA,并且当我们强迫客户接受此时,我们不能让他接受有缺陷的软件部分会影响一系列不相关的功能.这个问题是关于健壮的架构,而不是开发过程.
感谢您的关注!
好的,所以在试图追踪第n次各种软件的依赖关系并复制各种人为所有不同的linux发行版做的工作后,我想知道是否有更好的方法来捆绑各种软件到.rpm或.deb文件中以便于分发.
我目前为此做的设置是各种工具的frankenstein怪物,但主要是Vagrant和libguestfs,它们是在Fedora中运行的源代码构建的,因为没有任何发行版实际发布它virt-diff.以下是我目前遵循的步骤:
.vmdk并调用它base-image..vmdk并调用它non-base-image.virt-diff差异比较两个图像和转储数据文件调用diff.diff到另一种格式,其中包含我需要的信息,没有任何废话,我不喜欢的东西/var.guestfish使用一堆copy-out命令生成脚本.guestfish脚本.diff因为guestfish无法执行此操作.我想知道是否有更好的方法来做到这一点.你认为会有,但我还没弄清楚.
我在SQL Server 2008上的SELECT/UPDATE上遇到了死锁问题.我从这个帖子中读到了答案:SQL Server在select/update或多个选择之间出现死锁,但我仍然不明白为什么会出现死锁.
我在以下测试用例中重新创建了这种情况.
我有一张桌子:
CREATE TABLE [dbo].[SessionTest](
[SessionId] UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL,
[ExpirationTime] DATETIME NOT NULL,
CONSTRAINT [PK_SessionTest] PRIMARY KEY CLUSTERED (
[SessionId] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[SessionTest]
ADD CONSTRAINT [DF_SessionTest_SessionId]
DEFAULT (NEWID()) FOR [SessionId]
GO
Run Code Online (Sandbox Code Playgroud)
我首先尝试从此表中选择一条记录,如果记录存在,则将到期时间设置为当前时间加上一些间隔.它使用以下代码完成:
protected Guid? GetSessionById(Guid sessionId, SqlConnection connection, SqlTransaction transaction)
{
Logger.LogInfo("Getting session by id");
using (SqlCommand …Run Code Online (Sandbox Code Playgroud) 在2.6中有一种新的操作称为批量操作.它类似于我的事务 - 用户可以指定一组写入并随后执行它们,如下所述
var bulk = db.users.initializeOrderedBulkOp();
bulk.insert( { user: "abc123", status: "A", points: 0 } );
bulk.insert( { user: "ijk123", status: "A", points: 0 } );
bulk.insert( { user: "mop123", status: "P", points: 0 } );
bulk.find( { status: "D" } ).remove();
bulk.find( { status: "P" } ).update( { $set: { comment: "Pending" } } );
bulk.execute();
Run Code Online (Sandbox Code Playgroud)
批量操作是原子的吗?潜在消费者是否会经历不可重复或幻读?
我有两个单元测试使用TypeMock Isolator来隔离和伪造来自asp.net的SqlMembershipProvider的方法.
在测试1中,我有:
Isolate.WhenCalled(
() =>
Membership.CreateUser(...)))
.WithExactArguments()
.WillThrow(new Exception());
Run Code Online (Sandbox Code Playgroud)
在测试2中,我有:
Isolate.WhenCalled(
() =>
Membership.CreateUser(...)))
.WithExactArguments()
.WillReturn(new MembershipUser(...));
Run Code Online (Sandbox Code Playgroud)
当我自己运行每个测试时,它们都成功通过.
当我运行两个测试时,测试编号1首先运行并通过,然后测试编号2运行并失败,测试1中抛出异常.
为什么WillThrow()测试1中的指令会"流失"到测试2?毕竟,测试2明确定义了不同的行为 - WillReturn()?
我有以下代码:
@Service
public class MyService implements IMyService {
@Inject
IAnotherService anotherService;
// injects go here
// some code
@Transactional(isolation=Isolation.SERIALIZABLE)
public Result myMethod() {
// stuff done here
return this.myPrivateMethod()
}
private Result myPrivateMethod() {
// stuff done here
// multiple DAO SAVE of anObject
anotherService.processSomething(anObject);
return result;
}
}
@Service
public class AnotherService implements IAnotherService {
// injections here
// other stuff
@Transactional(isolation=SERIALIZABLE)
public Result processSomething(Object anObject) {
// some code here
// multiple dao save
// manipulation of anObject …Run Code Online (Sandbox Code Playgroud) 我在这里寻找指针和信息,我会做这个CW,因为我怀疑它没有一个正确答案.这是针对C#的,因此我将在下面对Linq进行一些引用.我也为这篇长篇大论道歉.让我在这里总结一下这个问题,然后是完整的问题.
简介:在UI/BLL/DAL/DB 4层应用程序中,如何更改用户界面,以显示更多列(例如在网格中),避免泄漏通过业务逻辑层进入数据访问层,掌握要显示的数据(假设它已经在数据库中).
让我们假设一个有3(4)层的分层应用程序:
在这种情况下,DAL负责构造SQL语句并对数据库执行它们,返回数据.
"正确"构建这样一个层的唯一方法就是总是"select*"吗?对我来说这是一个很大的禁忌,但让我解释为什么我在想.
让我们说,对于我的用户界面,我希望显示所有拥有活跃就业记录的员工."活跃"是指今天的就业记录包含今天(或者甚至是我可以在用户界面中设定的日期).
在这种情况下,假设我想向所有这些人发送一封电子邮件,因此我在BLL中有一些代码可以确保我还没有向同一个人发送过电子邮件,等等.
对于BLL,它需要最少量的数据.也许它调用数据访问层来获取活动员工列表,然后调用以获取它发送的电子邮件列表.然后它加入这些并构造一个新列表.也许这可以在数据访问层的帮助下完成,这并不重要.
重要的是,对于业务层,它实际上并不需要太多数据.也许它只需要每个员工的唯一标识符,对于两个列表,匹配,然后说"这些是活动的那些的唯一标识符,您还没有发送电子邮件到".然后构建DAL代码,构造只检索业务层需要的SQL语句吗?IE浏览器.只是"SELECT id FROM employees WHERE ..."?
那么我该怎么做用户界面呢?对于用户来说,这或许会是最好的,包括了很多信息,这取决于为什么我要发送电子邮件.例如,我可能想要包括一些基本的联系信息,或者他们工作的部门,或者他们的经理姓名等,而不是说我至少要显示姓名和电子邮件地址信息.
用户界面如何获取数据?我是否更改了DAL以确保将足够的数据返回给UI?我是否更改BLL以确保它为UI返回足够的数据?如果从DAL返回到BLL的对象或数据结构也可以发送到UI,那么BLL可能不需要进行太多的更改,但是UI的要求会影响超出应该与之通信的层. .如果这两个世界在不同的数据结构上运行,则可能必须对两者进行更改.
那么当UI被更改时,为了进一步帮助用户,通过添加更多列,我需要多深才能更改UI?(假设数据已存在于数据库中,因此不需要进行任何更改.)
提出的一个建议是使用Linq-To-SQL和IQueryable,这样如果DAL处理什么(如在什么类型的数据中)和为什么(如WHERE-clauses中)返回IQueryables,那么BLL可以可能会将这些内容返回到UI,然后可以构建一个Linq查询来检索所需的数据.然后,用户界面代码可以拉入所需的列.这将有效,因为使用IQuerables,UI最终会实际执行查询,然后它可以使用"select new {X,Y,Z}"来指定它需要的内容,甚至可以在必要时加入其他表.
这看起来很混乱.UI执行SQL代码本身,即使它已隐藏在Linq前端后面.
但是,为了实现这一点,不应该允许BLL或DAL关闭数据库连接,并且在IoC类型的世界中,DAL服务可能比UI代码所希望的更快地被处理掉,因此Linq查询可能最终会出现"无法访问已处置对象"的异常.
所以我正在寻找指针.我们有多远?你是怎么处理的?我认为UI的更改将通过BLL泄漏到DAL中是一个非常糟糕的解决方案,但是现在它看起来并不像我们能做得更好.
请告诉我我们有多愚蠢并证明我错了?
请注意,这是一个遗留系统.多年来,更改数据库模式的范围还不在范围内,因此使用ORM对象的解决方案基本上与"select*"相当,实际上并不是一种选择.我们有一些大型表格,我们希望避免在整个图层列表中提取.
c# business-logic data-access-layer isolation leaky-abstraction
我对Oracle阻塞有一点了解 - 更新如何阻止其他更新,直到事务完成,编写器如何阻止读取器等.
我理解悲观和优化锁定的概念,以及关于丢失丢失更新的典型银行教科书示例等.
我也理解JDBC事务隔离级别,例如,我们很高兴看到未提交的数据.
然而,我对这些概念如何相关和相互作用有点模糊.例如:
任何澄清这些主题的话都会非常感激!
在大型软件实现中,通常建议在API设计与其实现之间进行分离.但在某个地方,它们必须重新连接(即,实现必须重新连接到API).
以下示例显示了API设计以及通过INSTANCE对象调用其实现:
import java.util.List;
public abstract class Separation {
public static final Separation INSTANCE = new SeparationImpl();
// Defining a special list
public static interface MySpecialList<T> extends List<T> {
void specialAdd(T item);
}
// Creation of a special list
public abstract <T> MySpecialList<T> newSpecialList(Class<T> c);
// Merging of a special list
public abstract <T> MySpecialList<? extends T> specialMerge(
MySpecialList<? super T> a, MySpecialList<? super T> b);
// Implementation of separation
public static class SeparationImpl extends Separation {
@Override
public <T> …Run Code Online (Sandbox Code Playgroud) 在我主要工作的linux中,我们使用一种称为CPU隔离的技术,它可以有效地将进程锁定到处理器上,还可以防止处理器运行其他任何东西.我们的内核人员做了一些魔术来处理中断.
在Windows中,我发现最接近的是一个亲和概念,它似乎将进程/线程绑定到处理器.但它不能保证处理器仅运行该进程/线程意味着仍然可以存在上下文切换和其他抖动.
有没有办法在Windows上隔离CPU以确定半确定的运行时间?